package com.minarto.display.loader {
	import com.minarto.utils.GPool;
	import de.polygonal.core.ObjectPool;
	import flash.display.*;
	import flash.net.URLRequest;
	import flash.events.*;

	/**
	 * @author minarto@minarto.com
	 */
	[Event(name = "complete", type = "flash.events.Event")]
	[Event(name = "ioError", type = "flash.events.IOErrorEvent")]
	[Event(name = "lastComplete", type = "com.minarto.events.CustomEvent")]
	public class ChainLoader extends EventDispatcher {
		private var _loader:Loader,
					_source:Vector.<String>,
					_contents:Vector.<DisplayObject>,
					_lastEvt:Event = new Event("lastComplete"),
					_currentIndex:int = - 1,
					_length:uint;
					
					
		public var	onComplete:Function,
					onLastComplete:Function,
					onIoError:Function;
		

		public function getContents():Vector.<DisplayObject> {
			return	_contents;
		}
		
		
		public function getContentAt($index:int):DisplayObject {
			return	_contents ? _contents[$index] : null;
		}
		
		
		public function getContent($src:String):DisplayObject {
			return	_contents ? _contents[$src] : null;
		}
		
		public function clear():void{
			_contents = null;
		}
		

		public function getCurrentIndex():int {
			return _currentIndex;
		}
		

		public function getLength():uint {
			return _length;
		}
		
		
		public function addSrc($src:String):void {
			if (!_source) {
				_source = new <String>[];
			}

			_length = _source.push($src);
		}
		
		
		public function load(...$src):void {
			var info:LoaderInfo, p:ObjectPool, r:URLRequest;
			
			close();
			
			_length = $src.length;
			if (_length) {
				if($src[0] is Array){
					_source = Vector.<String>($src[0]);
					_length = _source.length;
				}
				else {
					_source = Vector.<String>($src);
				}
			}
			else {
				_length = _source.length;
			}
			
			_currentIndex = 0;
			_contents = new <DisplayObject>[];
			
			if (_length) {
				p = GPool.getPool(Loader);
				_loader = p.object;
			
				info = _loader.contentLoaderInfo;
				info.addEventListener(Event.COMPLETE, _onComplete, false, 0, true);
				info.addEventListener(IOErrorEvent.IO_ERROR, _onIoError, false, 0, true);
			
				p = GPool.getPool(URLRequest);
				r = p.object;
				r.url = _source[_currentIndex];
				
				_loader.load(r);
				
				p.object = r;
			}
		}
		
		
		public function close():void {
			var info:LoaderInfo;
			
			if(_loader){
				_loader.close();
				
				info = _loader.contentLoaderInfo;
				info.removeEventListener(Event.COMPLETE, _onComplete);
				info.removeEventListener(IOErrorEvent.IO_ERROR, _onIoError);
			
				GPool.getPool(Loader).object = _loader;
				_loader = null;
			}
		}
		
		
		private function _onComplete($e:Event):void {
			var info:LoaderInfo, p:ObjectPool, r:URLRequest, d:DisplayObject;
			
			info = _loader.contentLoaderInfo;
			
			d = info.content;
			
			_contents.push(d);
			
			dispatchEvent($e);
			
			if (_currentIndex < _length - 1) {
				p = GPool.getPool(URLRequest);
				r = p.object;
				r.url = _source[++ _currentIndex];
				
				_loader.load(r);
				
				p.object = r;
			}
			else {
				_currentIndex = - 1;
				dispatchEvent(_lastEvt);
				
				if(Boolean(onLastComplete)){
					onLastComplete(this);
				}
				
				info.removeEventListener(Event.COMPLETE, _onComplete);
				info.removeEventListener(IOErrorEvent.IO_ERROR, _onIoError);
			
				p = GPool.getPool(Loader);
				p.object = _loader;
				_loader = null;
			}
		}
		
		
		private function _onIoError($e:IOErrorEvent):void {
			_contents.push(null);
			
			dispatchEvent($e);
			
			if(Boolean(onIoError)){
				onIoError(this);
			}
		}
	}
}